from decimal import Decimal

from livesettings import config_value

from django.core.urlresolvers import reverse
from django.forms import ValidationError
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.utils.safestring import mark_safe
from django.utils.simplejson.encoder import JSONEncoder
from django.utils.translation import ugettext_lazy as _
from django.views.decorators.cache import never_cache

from satchmo_store.contact.models import Contact
from satchmo_store.shop.models import Cart, Order, Config
from satchmo_store.shop.forms import MultipleProductForm
from satchmo_store.shop.signals import satchmo_cart_changed, satchmo_cart_details_query, satchmo_cart_add_complete
from satchmo_store.shop.templatetags.satchmo_currency import currency
from satchmo_utils.numbers import RoundedDecimalField
from satchmo_utils.templatetags.normalize_decimal import normalize_decimal
from satchmo_utils.views import bad_or_missing

from payment.decorators import cart_has_minimum_order
from product.models import Category, Product

from satchmo_tuning.forms import QuickOrderForm

def _set_cart_item_qty(request, cart, products, slug, quantity):
    try:
        product = products.get(slug=slug)
        if quantity > 0:
            details = {}
            satchmo_cart_details_query.send(cart, product=product, quantity=quantity,
                                            details=details, request=request, form=request.POST)
            added_item = cart.add_item(product, number_added=quantity, details=details)
            added_item.quantity = quantity
            added_item.save()
            satchmo_cart_add_complete.send(cart, cart=cart, cartitem=added_item, 
                                           product=product, request=request, form=request.POST)
        elif quantity == 0:
            for item in cart.cartitem_set.filter(product=product):
                item.delete()
                cart.save()
    except Product.DoesNotExist:
        pass

def cart_add_multiple_ajax(request):

    cart = None

    if request.method == "POST":

        products = Product.objects.active_by_site()
        decimal_field = RoundedDecimalField() # satchmo uses this class to normalize qty values

        cart = Cart.objects.from_request(request, create=True)
        for name, value in request.POST.items():
            if name.startswith("qty__"):
                slug = name[len("qty__"):]
                try:
                    quantity = decimal_field.clean(value)
                    _set_cart_item_qty(request, cart, products, slug, quantity)
                except ValidationError:
                    pass
        satchmo_cart_changed.send(cart, cart=cart, request=request)

    if not cart:
        cart = Cart.objects.from_request(request, create=False)

    if cart:
        cart_count = normalize_decimal(cart.numItems)
        cart_total = currency(cart.total)
        items = cart.cartitem_set.all()
        items_in_cart = dict([(item.product.slug, str(item.quantity)) for item in items])
    else:
        cart_count = 0
        cart_total = ''
        items_in_cart = {}


    data = {
        'cart_count': cart_count,
        'cart_total': cart_total,
        'items_in_cart': items_in_cart
    }

    encoded = JSONEncoder().encode(data)
    encoded = mark_safe(encoded)
    return render_to_response('shop/json.html', {'json' : encoded})


def checkout(request):

    cart = Cart.objects.from_request(request)
    if cart.numItems == 0:
        return render_to_response('shop/checkout/empty_cart.html', RequestContext(request))

    if not request.user.is_authenticated() and config_value('SHOP', 'AUTHENTICATION_REQUIRED'):
        url = reverse('satchmo_checkout_auth_required')
        thisurl = reverse('satchmo_tuning_checkout')
        return HttpResponseRedirect(url + "?next=" + thisurl)

    shop = Config.objects.get_current()
    try:
        contact = Contact.objects.from_request(request, create=False)
    except Contact.DoesNotExist:
        contact = None

    if request.method == 'POST':
        form = QuickOrderForm(data=request.POST.copy(),
                              shop=shop,
                              contact=contact,
                              shippable=cart.is_shippable, 
                              cart=cart)
        if form.is_valid():
            contact = Contact.objects.from_request(request, create=True)
            order = form.save(cart=cart, contact=contact)
            request.session['orderID'] = order.id            
            success = reverse('satchmo_tuning_checkout_success')
            return HttpResponseRedirect(success)
    else:
        initial = {}
        if request.user.is_authenticated():
            initial.update({'first_name': request.user.first_name,
                            'last_name': request.user.last_name,
                            'email': request.user.email,})
        form = QuickOrderForm(shop=shop, 
                              contact=contact, 
                              shippable=cart.is_shippable, 
                              initial=initial, 
                              cart=cart)

    context = RequestContext(request, {'form': form})
    return render_to_response('shop/checkout/quick_order_form.html', context)

checkout = never_cache(cart_has_minimum_order()(checkout))


def checkout_success(request):
    try:
        order = Order.objects.from_request(request)
        del request.session['orderID']
    except Order.DoesNotExist:
        return bad_or_missing(request, _('Your order has already been processed.'))
    context = RequestContext(request, {'order': order})
    return render_to_response('shop/checkout/success.html', context)

checkout_success = never_cache(checkout_success)
